use crate::codec::d_codec::{Packet, Transmission};
use crate::serializer::serialization::{DeSerialized, Serialized};
use crate::start::server::Message;
use bytes::Bytes;
use bytes::{BufMut, BytesMut};
use std::net::SocketAddr;
use tokio::sync::mpsc::UnboundedSender;

pub mod dispatcher;
pub mod server;
pub mod shutdown;
pub mod tcp;
pub mod udp;
pub mod connection;
pub mod processor;

#[derive(Default)]
pub struct SendMsg<T> {
    rpc_num: Option<i8>,
    cmd: Option<i16>,
    flags: Option<i8>,
    serialization_type: Option<i8>,
    lrc: Option<i8>,
    body: Option<Bytes>,
    msg: Option<T>,
}
#[derive(Default)]
pub struct SendPacket {
    rpc_num: Option<i8>,
    cmd: Option<i16>,
    flags: Option<i8>,
    serialization_type: Option<i8>,
    lrc: Option<i8>,
    body: Option<Bytes>,
}
impl<T> SendMsg<T> {
    pub fn from(packet: &Packet) -> Self {
        SendMsg {
            rpc_num: Some(packet.get_rpc_num()),
            cmd: Some(packet.get_cmd()),
            flags: Some(packet.get_flags()),
            serialization_type: Some(packet.get_serialization_type()),
            lrc: Some(packet.get_lrc()),
            body: Some(packet.get_body().clone()),
            msg: None,
        }
    }
}

#[derive(Debug)]
pub struct Connection {
    packet: Packet,
    send: UnboundedSender<Message>,
    addr: SocketAddr,
}
impl Connection {
    pub fn send_packet(&self, send_msg: SendPacket) {
        let mut packet = self.packet.clone();
        if let Some(rpc_num) = send_msg.rpc_num {
            packet.set_rpc_num(rpc_num);
        }
        if let Some(cmd) = send_msg.cmd {
            packet.set_cmd(cmd)
        }
        if let Some(flags) = send_msg.flags {
            packet.set_flags(flags)
        }
        if let Some(serialization) = send_msg.serialization_type {
            packet.set_serialization_type(serialization)
        }
        if let Some(lrc) = send_msg.lrc {
            packet.set_lrc(lrc)
        }
        if let Some(body) = send_msg.body {
            packet.set_body(body)
        }
        self.send.send(Message::Send(packet, self.addr));
    }
    pub fn send_msg<T: Serialized>(&self, send_msg: SendMsg<T>) {
        let mut packet = self.packet.clone();
        if let Some(rpc_num) = send_msg.rpc_num {
            packet.set_rpc_num(rpc_num);
        }
        if let Some(cmd) = send_msg.cmd {
            packet.set_cmd(cmd)
        }
        if let Some(flags) = send_msg.flags {
            packet.set_flags(flags)
        }
        if let Some(serialization) = send_msg.serialization_type {
            packet.set_serialization_type(serialization)
        }
        if let Some(lrc) = send_msg.lrc {
            packet.set_lrc(lrc)
        }
        if let Some(body) = send_msg.body {
            packet.set_body(body)
        } else if let Some(msg) = send_msg.msg {
            let bytes = msg.serialized();
            // let mut bytes_mut = BytesMut::new();
            // bytes_mut.put_slice(bytes.as_ref());
            // let mut x = packet.get_body();
            packet.set_body(bytes);
        }
        self.send.send(Message::Send(packet, self.addr));
    }
    pub fn de_serialized<'a,T: DeSerialized>(&'a self, de_serialized: &'a mut T) -> &mut T {
        let packet = &self.packet;
        let x = packet.get_body();
        de_serialized.deserialized(x)
    }
    pub fn get_packet(&self) -> &Packet {
        &self.packet
    }
    pub fn get_socket_addr(&self) -> &SocketAddr {
        &self.addr
    }
}
